﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using DotSpatial.Controls;
using DotSpatial.Topology;
using System.Drawing;
using Point = System.Drawing.Point;
using System.Diagnostics;
using System.Windows.Forms;
using SelectionMode = DotSpatial.Symbology.SelectionMode;
using DotSpatial.Symbology;
using System.Drawing.Drawing2D;
using DotSpatial.Data;

namespace HAGISV2
{
   public class HEditHydrolicGridMF:HMapFunction
    {
       public HEditHydrolicGridMF(IMap map)
           : base(map)
       {
           _editGridMode = MFEDITGRIDMODE.None;
           Configure();
 
       }
       #region public properties

       MFEDITGRIDMODE _editGridMode;

       public MFEDITGRIDMODE EditGridMode
       {
           get { return _editGridMode; }
           set { _editGridMode = value; }
       }


       HydrolicGridLayer _thisLayer;



       #endregion



       #region 
       Point pointFirst;
       Point pointSecend;
       Coordinate coordFirst;
       Coordinate coordSecend;
       bool _isDragging;

       Polygon bounderPoly;

       Coordinate movingNode;
       int itemColIndex, itemRowIndex, itemIndex;

       bool IsCtrlPressing = false;
       private Point _currentPoint;

       private ContextMenuStrip _context;

       public ContextMenuStrip Context
       {
           get { return _context; }
           set { _context = value; }
       }


       #endregion

       private void Configure()
       {
           YieldStyle = (YieldStyles.LeftButton | YieldStyles.RightButton | YieldStyles.Keyboard);
                      
       }

        #region method

       protected override void OnActivate()
       {
           if (_standBy == false)
           {
               //初始化一些东西=================================
               switch (_editGridMode)
               {
                   case MFEDITGRIDMODE.None:
                       break;
                   case MFEDITGRIDMODE.EditByNode:


                       break;

                   case MFEDITGRIDMODE.SelectByCell:



                       break;

                   case MFEDITGRIDMODE.SelectByColCell:


                       break;

                   case MFEDITGRIDMODE.SelectByRowCell:


                       break;

                   case MFEDITGRIDMODE.SelectByLayer:


                       break;

                   case MFEDITGRIDMODE.AddCol:

                       break;

                   case MFEDITGRIDMODE.AddRow:

                       
                       break;

                   default: break;

               }

           }

           _standBy = false;

           base.OnActivate();
       }


       protected override void OnDeactivate()
       {
           _standBy = true;
           switch (_editGridMode)
           {
               case MFEDITGRIDMODE.None:
                   break;
               case MFEDITGRIDMODE.EditByNode:



                   break;

               case MFEDITGRIDMODE.SelectByCell:


                   break;

               case MFEDITGRIDMODE.SelectByColCell:

                   break;

               case MFEDITGRIDMODE.SelectByRowCell:

                   break;

               case MFEDITGRIDMODE.SelectByLayer:


                   break;

               case MFEDITGRIDMODE.AddCol:

                   break;

               case MFEDITGRIDMODE.AddRow:

                   break;

               default: break;

           }


           base.OnDeactivate();
       }

       bool _isMoved = false;
       bool _isMovingEnd = true;
       LineSegment[] movingSegment;
       bool _isMovingValid;
       Coordinate botChangedCoord;
       Coordinate leftChangedCoord;

       bool GetMovingNodeSegments(GeoMouseArgs e,out LineSegment[] movingSegs)
       {

           movingSegs = new LineSegment[2];
           LineSegment topSeg, leftSeg, rightSeg, botSeg;
           topSeg = _thisLayer.GridLines[0];
           leftSeg = _thisLayer.GridLines[_thisLayer.HyGrid.RowsCount+1];
           rightSeg = _thisLayer.GridLines[_thisLayer.GridLines.Count - 1];
           botSeg = _thisLayer.GridLines[_thisLayer.HyGrid.RowsCount];

           //为边界节点设置
           Coordinate innerControler, outerControler;

           Polygon extentPoly;

           //未进行边界控制，该函数只在正确情况下调用
           List<Coordinate> bounder = _thisLayer.GetGridAngularCoordinates();
           List<Coordinate> polyCoords = new List<Coordinate>();

           #region 边框节点控制
           if (itemRowIndex == 0)
               if (itemColIndex == 0)
               {
                   innerControler = _thisLayer.GridCoordinates[_thisLayer.HyGrid.ColsCount + 2];
                   polyCoords.Add(e.GeographicLocation);
                   polyCoords.Add(rightSeg.Project(e.GeographicLocation));
                   polyCoords.Add(bounder[2]);
                   polyCoords.Add(botSeg.Project(e.GeographicLocation));
                   polyCoords.Add(e.GeographicLocation);

                   extentPoly = new Polygon(polyCoords);
                   if (extentPoly.Contains(new DotSpatial.Topology.Point(innerControler)))
                   {
                       leftChangedCoord = leftSeg.Project(e.GeographicLocation);
                       botChangedCoord = botSeg.Project(e.GeographicLocation);
                       movingSegs[0] = new LineSegment(e.GeographicLocation, rightSeg.Project(e.GeographicLocation));
                       movingSegs[1] = new LineSegment(e.GeographicLocation, botChangedCoord);
                       return true;
                   }
                   return false;
               }
               else if (itemColIndex == _thisLayer.HyGrid.ColsCount)
               {
                   innerControler = _thisLayer.GridCoordinates[_thisLayer.HyGrid.ColsCount * 2];
                   polyCoords.Add(e.GeographicLocation);
                   polyCoords.Add(botSeg.Project(e.GeographicLocation));
                   polyCoords.Add(bounder[3]);
                   polyCoords.Add(leftSeg.Project(e.GeographicLocation));
                   polyCoords.Add(e.GeographicLocation);

                   extentPoly = new Polygon(polyCoords);
                   if (extentPoly.Contains(new DotSpatial.Topology.Point(innerControler)))
                   {
                       botChangedCoord = botSeg.Project(e.GeographicLocation);
                       leftChangedCoord = leftSeg.Project(e.GeographicLocation);
                       movingSegs[0] = new LineSegment(e.GeographicLocation, botChangedCoord);
                       movingSegs[1] = new LineSegment(e.GeographicLocation, leftChangedCoord);
                       return true;
                   }
                   return false;

               }
               else
               {
                   innerControler = _thisLayer.GridCoordinates[_thisLayer.HyGrid.ColsCount + 2 + itemColIndex];
                   outerControler = _thisLayer.GridCoordinates[_thisLayer.HyGrid.ColsCount + itemColIndex];
                   LineSegment intersectSeg = new LineSegment(innerControler, outerControler);
                   LineSegment projSeg = new LineSegment(e.GeographicLocation, botSeg.Project(e.GeographicLocation));

                   polyCoords.Add(e.GeographicLocation);
                   polyCoords.Add(rightSeg.Project(e.GeographicLocation));
                   polyCoords.Add(bounder[2]);
                   polyCoords.Add(botSeg.Project(e.GeographicLocation));
                   polyCoords.Add(e.GeographicLocation);

                   extentPoly = new Polygon(polyCoords);
                   if (intersectSeg.Intersection(projSeg)!=null && !extentPoly.Contains(new DotSpatial.Topology.Point(outerControler)))
                   {
                       botChangedCoord = botSeg.Project(e.GeographicLocation);
                       leftChangedCoord = leftSeg.Project(e.GeographicLocation);
                       movingSegs[0] = new LineSegment(leftChangedCoord, rightSeg.Project(e.GeographicLocation));
                       movingSegs[1] = new LineSegment(e.GeographicLocation, botChangedCoord);
                       return true;
                   }
                   return false;
               }
           if (itemRowIndex == _thisLayer.HyGrid.RowsCount)
               if (itemColIndex == 0)
               {
                   innerControler = _thisLayer.GridCoordinates[_thisLayer.GridCoordinates.Count-_thisLayer.HyGrid.ColsCount*2-1];
                   polyCoords.Add(e.GeographicLocation);
                   polyCoords.Add(topSeg.Project(e.GeographicLocation));
                   polyCoords.Add(bounder[1]);
                   polyCoords.Add(rightSeg.Project(e.GeographicLocation));
                   polyCoords.Add(e.GeographicLocation);

                   extentPoly = new Polygon(polyCoords);
                   if (extentPoly.Contains(new DotSpatial.Topology.Point(innerControler)))
                   {
                       leftChangedCoord = leftSeg.Project(e.GeographicLocation);
                       botChangedCoord = botSeg.Project(e.GeographicLocation);
                       movingSegs[0] = new LineSegment(e.GeographicLocation, topSeg.Project(e.GeographicLocation));
                       movingSegs[1] = new LineSegment(e.GeographicLocation, rightSeg.Project(e.GeographicLocation));
                       return true;
                   }
                   return false;

               }
               else if (itemColIndex == _thisLayer.HyGrid.ColsCount)
               {
                   innerControler = _thisLayer.GridCoordinates[_thisLayer.GridCoordinates.Count-_thisLayer.HyGrid.ColsCount-3];
                   polyCoords.Add(e.GeographicLocation);
                   polyCoords.Add(leftSeg.Project(e.GeographicLocation));
                   polyCoords.Add(bounder[0]);
                   polyCoords.Add(topSeg.Project(e.GeographicLocation));
                   polyCoords.Add(e.GeographicLocation);

                   extentPoly = new Polygon(polyCoords);
                   if (extentPoly.Contains(new DotSpatial.Topology.Point(innerControler)))
                   {
                       leftChangedCoord = leftSeg.Project(e.GeographicLocation);
                       botChangedCoord = botSeg.Project(e.GeographicLocation);
                       movingSegs[0] = new LineSegment(e.GeographicLocation, leftChangedCoord);
                       movingSegs[1] = new LineSegment(e.GeographicLocation, topSeg.Project(e.GeographicLocation));
                       return true;
                   }
                   return false;
               }
               else
               {
                   innerControler = _thisLayer.GridCoordinates[_thisLayer.GridCoordinates.Count - _thisLayer.HyGrid.ColsCount * 2 - 1 + itemColIndex];
                   outerControler = _thisLayer.GridCoordinates[_thisLayer.GridCoordinates.Count - _thisLayer.HyGrid.ColsCount * 2 - 3 + itemColIndex];
                   LineSegment intersectSeg = new LineSegment(innerControler, outerControler);
                   LineSegment projSeg = new LineSegment(e.GeographicLocation, topSeg.Project(e.GeographicLocation));

                   polyCoords.Add(e.GeographicLocation);
                   polyCoords.Add(topSeg.Project(e.GeographicLocation));
                   polyCoords.Add(bounder[1]);
                   polyCoords.Add(rightSeg.Project(e.GeographicLocation));
                   polyCoords.Add(e.GeographicLocation);

                   
                   extentPoly = new Polygon(polyCoords);
                   if (intersectSeg.Intersection(projSeg) != null && !extentPoly.Contains(new DotSpatial.Topology.Point(outerControler)))
                   {
                       leftChangedCoord = leftSeg.Project(e.GeographicLocation);
                       botChangedCoord = botSeg.Project(e.GeographicLocation);
                       movingSegs[0] = new LineSegment(leftChangedCoord, rightSeg.Project(e.GeographicLocation));
                       movingSegs[1] = new LineSegment(e.GeographicLocation, topSeg.Project(e.GeographicLocation));
                       return true;
                   }
                   return false;
               }
           if (itemColIndex == 0)
           {
               innerControler = _thisLayer.GridCoordinates[_thisLayer.HyGrid.ColsCount + 2 + (itemRowIndex) * (_thisLayer.HyGrid.ColsCount + 1)];
               outerControler = _thisLayer.GridCoordinates[_thisLayer.HyGrid.ColsCount + 2 + (itemRowIndex - 2) * (_thisLayer.HyGrid.ColsCount + 1)];
               LineSegment intersectSeg = new LineSegment(innerControler, outerControler);
               LineSegment projSeg = new LineSegment(e.GeographicLocation, rightSeg.Project(e.GeographicLocation));

               polyCoords.Add(e.GeographicLocation);
               polyCoords.Add(rightSeg.Project(e.GeographicLocation));
               polyCoords.Add(bounder[2]);
               polyCoords.Add(botSeg.Project(e.GeographicLocation));
               polyCoords.Add(e.GeographicLocation);

               extentPoly = new Polygon(polyCoords);
               if (intersectSeg.Intersection(projSeg)!=null && !extentPoly.Contains(new DotSpatial.Topology.Point(outerControler)))
               {
                   leftChangedCoord = leftSeg.Project(e.GeographicLocation);
                   botChangedCoord = botSeg.Project(e.GeographicLocation);
                   movingSegs[0] = new LineSegment(topSeg.Project(e.GeographicLocation), botChangedCoord);
                   movingSegs[1] = new LineSegment(e.GeographicLocation, rightSeg.Project(e.GeographicLocation));
                   return true;
               }
               return false;
           }
           if (itemColIndex == _thisLayer.HyGrid.ColsCount)
           {
               innerControler = _thisLayer.GridCoordinates[_thisLayer.HyGrid.ColsCount * 2 + (itemRowIndex) * (_thisLayer.HyGrid.ColsCount + 1)];
               outerControler = _thisLayer.GridCoordinates[_thisLayer.HyGrid.ColsCount * 2 + (itemRowIndex - 2) * (_thisLayer.HyGrid.ColsCount + 1)];
               LineSegment intersectSeg = new LineSegment(innerControler, outerControler);
               LineSegment projSeg = new LineSegment(e.GeographicLocation, leftSeg.Project(e.GeographicLocation));

               polyCoords.Add(e.GeographicLocation);
               polyCoords.Add(botSeg.Project(e.GeographicLocation));
               polyCoords.Add(bounder[3]);
               polyCoords.Add(leftSeg.Project(e.GeographicLocation));
               polyCoords.Add(e.GeographicLocation);

               extentPoly = new Polygon(polyCoords);
               if (intersectSeg.Intersection(projSeg)!=null && !extentPoly.Contains(new DotSpatial.Topology.Point(outerControler)))
               {
                   botChangedCoord = botSeg.Project(e.GeographicLocation);
                   leftChangedCoord = leftSeg.Project(e.GeographicLocation);
                   movingSegs[0] = new LineSegment(topSeg.Project(e.GeographicLocation), botChangedCoord);
                   movingSegs[1] = new LineSegment(e.GeographicLocation,leftChangedCoord);
                   return true;
               }
               return false;
           }
           #endregion

           #region 内部节点控制
           innerControler = e.GeographicLocation;

           polyCoords.Add(_thisLayer.GridCoordinates[itemIndex - _thisLayer.HyGrid.ColsCount - 2]);
           polyCoords.Add(_thisLayer.GridCoordinates[itemIndex - _thisLayer.HyGrid.ColsCount]);
           polyCoords.Add(_thisLayer.GridCoordinates[itemIndex + _thisLayer.HyGrid.ColsCount + 2]);
           polyCoords.Add(_thisLayer.GridCoordinates[itemIndex + _thisLayer.HyGrid.ColsCount]);
           polyCoords.Add(_thisLayer.GridCoordinates[itemIndex - _thisLayer.HyGrid.ColsCount - 2]);

           extentPoly = new Polygon(polyCoords);
           if (extentPoly.Contains(new DotSpatial.Topology.Point(innerControler)) )
           {
               botChangedCoord = botSeg.Project(e.GeographicLocation);
               leftChangedCoord = leftSeg.Project(e.GeographicLocation);
               movingSegs[0] = new LineSegment(topSeg.Project(e.GeographicLocation), botChangedCoord);
               movingSegs[1] = new LineSegment(leftChangedCoord, rightSeg.Project(e.GeographicLocation));
               return true;
           }
           return false;

           #endregion
       }


       protected override void OnDraw(MapDrawArgs e)
       {
           if ((_thisLayer = this.InteractiveSystem.CurrentLayer as HydrolicGridLayer) == null) return;
           if (_standBy) return;
           switch (_editGridMode)
           {
               case MFEDITGRIDMODE.None:
                   break;
               case MFEDITGRIDMODE.EditByNode:
                   if (_thisLayer.ViewMode != FMAPVIEW.NORMAL) return;
                   if (!_isMovingEnd)
                   {
                       if (movingNode != Coordinate.Empty && movingNode != null)
                       {
                           if (!_isMovingValid) return;
                           GraphicsPath gp = new GraphicsPath();
                           gp.AddLine(Map.ProjToPixel(movingSegment[0].P0), Map.ProjToPixel(movingSegment[0].P1));
                           GraphicsPath gp1 = new GraphicsPath();
                           gp1.AddLine(Map.ProjToPixel(movingSegment[1].P0), Map.ProjToPixel(movingSegment[1].P1));

                           e.Graphics.DrawPath(new Pen(Color.LightSeaGreen, 1.5f), gp);
                           e.Graphics.DrawPath(new Pen(Color.LightSeaGreen, 1.5f), gp1);
                           gp.Dispose();
                           gp1.Dispose();
                           Map.Invalidate();
                           return;
                       }
                   }
                   break;

               case MFEDITGRIDMODE.SelectByCell:


                   break;

               case MFEDITGRIDMODE.SelectByColCell:

                   break;

               case MFEDITGRIDMODE.SelectByRowCell:

                   break;

               case MFEDITGRIDMODE.SelectByLayer:


                   break;

               case MFEDITGRIDMODE.AddCol:

                   break;

               case MFEDITGRIDMODE.AddRow:

                   break;

               default: break;

           }


           if (_isDragging)
           {
               // don't draw anything unless we need to draw a select rectangle
               Rectangle r = Opp.RectangleFromPoints(pointFirst, _currentPoint);
               r.Width -= 1;
               r.Height -= 1;
               //e.Graphics.DrawRectangle(Pens.White, r);
               e.Graphics.DrawRectangle(new Pen(Color.Black) { DashStyle = DashStyle.Dash }, r);
           }
           

           base.OnDraw(e);
       }



       protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
       {
           if ((_thisLayer = this.InteractiveSystem.CurrentLayer as HydrolicGridLayer) == null) return;

           if (_standBy) return;
           switch (e.KeyCode)
           {
               case System.Windows.Forms.Keys.ControlKey:
                   IsCtrlPressing = true;
                   break;


               case System.Windows.Forms.Keys.Delete:
                   this.InteractiveSystem.CurrentLayer.ClearSelection();
                   break;

               default: break;
           }
           
           base.OnKeyDown(e);
       }

       protected override void OnKeyUp(System.Windows.Forms.KeyEventArgs e)
       {
           if ((_thisLayer = this.InteractiveSystem.CurrentLayer as HydrolicGridLayer) == null) return;

           if (_standBy) return;
           //ctrl键操作
           if (e.KeyCode == System.Windows.Forms.Keys.ControlKey)
               IsCtrlPressing = false;

           base.OnKeyUp(e);
       }

       protected override void OnMouseDoubleClick(GeoMouseArgs e)
       {
           if ((_thisLayer = this.InteractiveSystem.CurrentLayer as HydrolicGridLayer) == null) return;

           if (_standBy) return;
           switch (_editGridMode)
           {
               case MFEDITGRIDMODE.None:
                   break;
               case MFEDITGRIDMODE.EditByNode:



                   break;

               //case MFEDITGRIDMODE.SelectByCell:
               //    //MessageBox.Show("Hello World!");

               //    break;

               //case MFEDITGRIDMODE.SelectByColCell:

               //    break;

               //case MFEDITGRIDMODE.SelectByRowCell:

               //    break;

               //case MFEDITGRIDMODE.SelectByLayer:


               //    break;

               case MFEDITGRIDMODE.AddCol:

                   break;

               case MFEDITGRIDMODE.AddRow:

                   break;

               default:
                   this.InteractiveSystem.GridCellDoubleClickAttribute();
                   break;
           }
           
           base.OnMouseDoubleClick(e);
       }

       protected override void OnMouseDown(GeoMouseArgs e)
       {
           if ((_thisLayer = this.InteractiveSystem.CurrentLayer as HydrolicGridLayer) == null) return;

           if (_standBy) return;

           //switch (_thisLayer.ViewMode)
           //{
           //    case FMAPVIEW.NORMAL:
           //        break;
           //    case FMAPVIEW.FRONT:
           //        break;
           //    case FMAPVIEW.RIGHT:
           //        break;
           //    default:
           //        break;
           //}

           if (e.Button == MouseButtons.Right) return;

           if (e.Button == MouseButtons.Middle) return;
           pointFirst = e.Location;
           coordFirst = e.GeographicLocation;
           Map.IsBusy = true;
           IEnvelope env;
           itemIndex = 0; itemColIndex = -1; itemRowIndex = -1; movingNode = Coordinate.Empty;
           switch (_editGridMode)
           {
               case MFEDITGRIDMODE.None:
                   return;
               case MFEDITGRIDMODE.EditByNode:
                   if (_thisLayer.ViewMode != FMAPVIEW.NORMAL) return;
                   env = new Envelope(coordFirst);
                   env.ExpandBy(Map.MapFrame.ViewExtents.Width / 450);
                   Polygon p = (Polygon)env.ToPolygon();
                   for (int i = 0; i <= _thisLayer.HyGrid.RowsCount; i++)
                   {
                       for (int j = 0; j <= _thisLayer.HyGrid.ColsCount; j++)
                       {
                           if (p.Intersects((DotSpatial.Topology.Point)_thisLayer.PtLayer.DataSet.Features[itemIndex].BasicGeometry))
                           {
                               itemRowIndex = i;
                               itemColIndex = j;
                               _thisLayer.PtLayer.Selection.Clear();
                               _thisLayer.PtLayer.Select(itemIndex);
                               DotSpatial.Topology.Point pt = (DotSpatial.Topology.Point)_thisLayer.PtLayer.DataSet.Features[itemIndex].BasicGeometry;
                               movingNode =new Coordinate(pt.X,pt.Y );
                               _isMovingEnd = false;
                               
                               return;
                           }
                           itemIndex++;
                       }
                   }


                   _isDragging = true;


                   break;

               case MFEDITGRIDMODE.SelectByCell:
                   _isDragging = true;


                   break;

               case MFEDITGRIDMODE.SelectByColCell:
                   _isDragging = true;
                   break;

               case MFEDITGRIDMODE.SelectByRowCell:
                   _isDragging = true;
                   break;

               case MFEDITGRIDMODE.SelectByLayer:
                   _isDragging = true;

                   break;

               case MFEDITGRIDMODE.AddCol:
                   for (int i = 0; i < _thisLayer.HyGrid.RowsCount; i++)
                   {
                       for (int j = 0; j < _thisLayer.HyGrid.ColsCount; j++)
                       {
                           if (((Polygon)_thisLayer.PyLayer.DataSet.Features[itemIndex].BasicGeometry).
                               Contains(new DotSpatial.Topology.Point(coordFirst)))
                           {
                               itemColIndex = j; break;
                           }
                           itemIndex++;
                       }
                       if (itemColIndex >= 0) break;
                   }
                   if (itemColIndex < 0) return;
                   //LineSegment ls;
                   LineSegment lsTop = new LineSegment(_thisLayer.TopColCoordinates[0], _thisLayer.TopColCoordinates[_thisLayer.TopColCoordinates.Count - 1]);
                   LineSegment lsBot = new LineSegment(_thisLayer.BottomCoordinates[0], _thisLayer.BottomCoordinates[_thisLayer.BottomCoordinates.Count - 1]);

                   
                   
                   //lsTop.Project(coordFirst);
                   //lsBot.Project(coordFirst);

                   break;

               case MFEDITGRIDMODE.AddRow:

                   break;

               default: break;
           }
           
           
           
           base.OnMouseDown(e);
       }


       protected override void OnMouseMove(GeoMouseArgs e)
       {
           if ((_thisLayer = this.InteractiveSystem.CurrentLayer as HydrolicGridLayer) == null) return;

           if (_standBy) return;


           int x, y, mx, my;
           switch (_editGridMode)
           {
               case MFEDITGRIDMODE.None:
                   return;
               case MFEDITGRIDMODE.EditByNode:
                   if (_thisLayer.ViewMode != FMAPVIEW.NORMAL) return;
                   if (!_isMovingEnd)
                   {
                       if (movingNode != Coordinate.Empty&&movingNode!=null)
                       {
                           _isMovingValid = GetMovingNodeSegments(e, out movingSegment);
                           _isMoved = true;
                           Map.Invalidate();

                       }
                       return;
                   }
                   base.OnMouseMove(e);

                   x = Math.Min(Math.Min(pointFirst.X, _currentPoint.X), e.X);
                   y = Math.Min(Math.Min(pointFirst.Y, _currentPoint.Y), e.Y);
                   mx = Math.Max(Math.Max(pointFirst.X, _currentPoint.X), e.X);
                   my = Math.Max(Math.Max(pointFirst.Y, _currentPoint.Y), e.Y);
                   _currentPoint = e.Location;
                   if (_isDragging)
                   {
                       Map.Invalidate(new Rectangle(x, y, mx - x, my - y));
                   }


                   break;

               case MFEDITGRIDMODE.SelectByCell:
                   base.OnMouseMove(e);

                   x = Math.Min(Math.Min(pointFirst.X, _currentPoint.X), e.X);
                   y = Math.Min(Math.Min(pointFirst.Y, _currentPoint.Y), e.Y);
                   mx = Math.Max(Math.Max(pointFirst.X, _currentPoint.X), e.X);
                   my = Math.Max(Math.Max(pointFirst.Y, _currentPoint.Y), e.Y);
                   _currentPoint = e.Location;
                   if (_isDragging)
                   {
                       Map.Invalidate(new Rectangle(x, y, mx - x, my - y));
                   }


                   break;

               case MFEDITGRIDMODE.SelectByColCell:
                   base.OnMouseMove(e);

                   x = Math.Min(Math.Min(pointFirst.X, _currentPoint.X), e.X);
                   y = Math.Min(Math.Min(pointFirst.Y, _currentPoint.Y), e.Y);
                   mx = Math.Max(Math.Max(pointFirst.X, _currentPoint.X), e.X);
                   my = Math.Max(Math.Max(pointFirst.Y, _currentPoint.Y), e.Y);
                   _currentPoint = e.Location;
                   if (_isDragging)
                   {
                       Map.Invalidate(new Rectangle(x, y, mx - x, my - y));
                   }


                   break;

               case MFEDITGRIDMODE.SelectByRowCell:
                   base.OnMouseMove(e);

                   x = Math.Min(Math.Min(pointFirst.X, _currentPoint.X), e.X);
                   y = Math.Min(Math.Min(pointFirst.Y, _currentPoint.Y), e.Y);
                   mx = Math.Max(Math.Max(pointFirst.X, _currentPoint.X), e.X);
                   my = Math.Max(Math.Max(pointFirst.Y, _currentPoint.Y), e.Y);
                   _currentPoint = e.Location;
                   if (_isDragging)
                   {
                       Map.Invalidate(new Rectangle(x, y, mx - x, my - y));
                   }


                   break;

               case MFEDITGRIDMODE.SelectByLayer:
                   base.OnMouseMove(e);

                   x = Math.Min(Math.Min(pointFirst.X, _currentPoint.X), e.X);
                   y = Math.Min(Math.Min(pointFirst.Y, _currentPoint.Y), e.Y);
                   mx = Math.Max(Math.Max(pointFirst.X, _currentPoint.X), e.X);
                   my = Math.Max(Math.Max(pointFirst.Y, _currentPoint.Y), e.Y);
                   _currentPoint = e.Location;
                   if (_isDragging)
                   {
                       Map.Invalidate(new Rectangle(x, y, mx - x, my - y));
                   }


                   break;

               case MFEDITGRIDMODE.AddCol:

                   break;

               case MFEDITGRIDMODE.AddRow:

                   break;

               default: break;
           }
           
       }

       protected override void OnMouseUp(GeoMouseArgs e)
       {
           if ((_thisLayer = this.InteractiveSystem.CurrentLayer as HydrolicGridLayer) == null) return;
           if (_standBy) return;
           Map.IsBusy = false;

           //if (this._editGridMode == MFEDITGRIDMODE.AddCol || this._editGridMode == MFEDITGRIDMODE.AddRow) return;
           if (e.Button==MouseButtons.Right)
           {
               if (bounderPoly == null)
               {
                   bounderPoly = new Polygon(_thisLayer.GetGridAngularCoordinates());
               }

               switch (_editGridMode)
               {
                   case MFEDITGRIDMODE.None:
                       break;
                   case MFEDITGRIDMODE.EditByNode:
                       if (_thisLayer.ViewMode != FMAPVIEW.NORMAL) return;
                       break;
                   case MFEDITGRIDMODE.SelectByCell:
                       for (int i = 0; i < _thisLayer.PyLayer.DataSet.Features.Count; i++)
                       {
                           if ( _thisLayer.PyLayer.DataSet.Features[i].Contains(new DotSpatial.Topology.Point(e.GeographicLocation)))
                           {
                               _context = this.InteractiveSystem.GridCellSelectContextMenu;
                               _context.Show(InteractiveSystem.GisManager.CurrentMap, e.Location);
                               break;
                           }
                       }
                       break;
                   case MFEDITGRIDMODE.SelectByRowCell:
                       for (int i = 0; i < _thisLayer.PyLayer.DataSet.Features.Count; i++)
                       {
                           if ( _thisLayer.PyLayer.DataSet.Features[i].Contains(new DotSpatial.Topology.Point(e.GeographicLocation)))
                           {
                               _context = this.InteractiveSystem.GridCellSelectContextMenu;
                               _context.Show(InteractiveSystem.GisManager.CurrentMap, e.Location);
                               break;
                           }
                       }
                       break;
                   case MFEDITGRIDMODE.SelectByColCell:
                       for (int i = 0; i < _thisLayer.PyLayer.DataSet.Features.Count; i++)
                       {
                           if ( _thisLayer.PyLayer.DataSet.Features[i].Contains(new DotSpatial.Topology.Point(e.GeographicLocation)))
                           {
                               _context = this.InteractiveSystem.GridCellSelectContextMenu;
                               _context.Show(InteractiveSystem.GisManager.CurrentMap, e.Location);
                               break;
                           }
                       }
                       break;
                   case MFEDITGRIDMODE.SelectByLayer:
                       break;
                   case MFEDITGRIDMODE.AddRow:
                       break;
                   case MFEDITGRIDMODE.AddCol:
                       break;
                   default:
                       break;
               }
                    

               return;
           }
           if (e.Button == MouseButtons.Left)
           {
               pointSecend = e.Location;
               coordSecend = e.GeographicLocation;
               if (this._editGridMode == MFEDITGRIDMODE.EditByNode)
               {
                   if (!_isDragging)
                   {
                       
                       _isMovingEnd = true;
                       if (!_isMovingValid) return;
                       _isMovingValid = false;
                       //double distance=0;
                       double rowDistance=0;
                       double colDistance=0;
                       double origonDis=0;
                       if (botChangedCoord != null && leftChangedCoord != null)
                       {
                           if (!_isMoved) return;
                           HyGrid hygrid = _thisLayer.HyGrid;
                           #region 原有直接更改网格方法，因添加主程控制修改为下面算法
                           //    if (itemColIndex == 0)//移动hygrid定义点时操作
                       //        if (itemRowIndex == _thisLayer.HyGrid.RowsCount)
                       //        {
                       //            //要看懂需思维比较清晰
                       //            //获取原有原点
                       //            Coordinate origin = hygrid.Origin;
                       //            //赋值新帮助原点X轴向，方便修改X轴向坐标点
                       //            hygrid.Origin = botChangedCoord;
                       //            hygrid.Origin.Z = hygrid.OrgZ;
                       //            hygrid.OrgX = botChangedCoord.X;
                       //            hygrid.OrgY = botChangedCoord.Y;
                       //            Coordinate helperCoord = _thisLayer.GridCoordinates[(hygrid.ColsCount + 1) * (hygrid.RowsCount) + 1];
                       //            distance = helperCoord.Distance(botChangedCoord);
                       //            origonDis = helperCoord.Distance(origin);
                       //            if (distance != helperCoord.Distance(origin))
                       //            {
                       //                distance -= origonDis;
                       //                //hygrid.ColCoords[0] = 0;
                       //                for (int i = 1; i < hygrid.ColCoords.Length; i++)
                       //                {
                       //                    hygrid.ColCoords[i] += distance;
                       //                }
                       //            }

                       //            //赋值新帮助原点Y轴向，方便修改Y轴向坐标点
                       //            hygrid.Origin = leftChangedCoord;
                       //            hygrid.Origin.Z = hygrid.OrgZ;
                       //            hygrid.OrgX = leftChangedCoord.X;
                       //            hygrid.OrgY = leftChangedCoord.Y;
                       //            helperCoord = _thisLayer.GridCoordinates[(hygrid.ColsCount + 1) * (hygrid.RowsCount - 1)];
                       //            distance = helperCoord.Distance(leftChangedCoord);
                       //            origonDis = helperCoord.Distance(origin);
                       //            if (distance != helperCoord.Distance(origin))
                       //            {
                       //                distance -= origonDis;
                       //                for (int i = 1; i < hygrid.RowCoords.Length; i++)
                       //                {
                       //                    hygrid.RowCoords[i] += distance;
                       //                }
                       //            }
                       //            //最后赋值新原点
                       //            hygrid.Origin = coordSecend;
                       //            hygrid.Origin.Z = hygrid.OrgZ;
                       //            hygrid.OrgX = coordSecend.X;
                       //            hygrid.OrgY = coordSecend.Y;
                       //        }
                       //        else
                       //        {
                       //            Coordinate origin = hygrid.Origin;
                       //            hygrid.RowCoords[hygrid.RowsCount - itemRowIndex] = hygrid.Origin.Distance(leftChangedCoord);
                       //            hygrid.Origin = botChangedCoord;
                       //            hygrid.Origin.Z = hygrid.OrgZ;
                       //            hygrid.OrgX = botChangedCoord.X;
                       //            hygrid.OrgY = botChangedCoord.Y;
                       //            Coordinate helperCoord = _thisLayer.GridCoordinates[(hygrid.ColsCount + 1) * (hygrid.RowsCount) + 1];
                       //            distance = helperCoord.Distance(botChangedCoord);
                       //            origonDis = helperCoord.Distance(origin);
                       //            if (distance != helperCoord.Distance(origin))
                       //            {
                       //                distance -= origonDis;
                       //                //hygrid.ColCoords[0] = 0;
                       //                for (int i = 1; i < hygrid.ColCoords.Length; i++)
                       //                {
                       //                    hygrid.ColCoords[i] += distance;
                       //                }
                       //            }
                       //        }
                       //    else if (itemRowIndex == _thisLayer.HyGrid.RowsCount)//移动hygrid定义点时操作
                       //    {
                       //        Coordinate origin = hygrid.Origin;
                       //        hygrid.ColCoords[itemColIndex] = hygrid.Origin.Distance(botChangedCoord);
                       //        hygrid.Origin = leftChangedCoord;
                       //        hygrid.Origin.Z = hygrid.OrgZ;
                       //        hygrid.OrgX = leftChangedCoord.X;
                       //        hygrid.OrgY = leftChangedCoord.Y;
                       //        Coordinate helperCoord = _thisLayer.GridCoordinates[(hygrid.ColsCount + 1) * (hygrid.RowsCount - 1)];
                       //        distance = helperCoord.Distance(leftChangedCoord);
                       //        origonDis = helperCoord.Distance(origin);
                       //        if (distance != helperCoord.Distance(origin))
                       //        {
                       //            distance -= origonDis;
                       //            //hygrid.ColCoords[0] = 0;
                       //            for (int i = 1; i < hygrid.RowCoords.Length; i++)
                       //            {
                       //                hygrid.RowCoords[i] += distance;
                       //            }
                       //        }
                       //    }
                       //    else//移动非Hygrid定义点时操作
                       //    {
                       //        hygrid.ColCoords[itemColIndex] = hygrid.Origin.Distance(botChangedCoord);
                       //        hygrid.RowCoords[hygrid.RowsCount - itemRowIndex] = hygrid.Origin.Distance(leftChangedCoord);
                       //    }
                           //    _thisLayer.HyGrid = hygrid;
                           #endregion

                           Coordinate origin = hygrid.Origin;
                           if (itemColIndex == 0)//移动hygrid定义点时操作
                               if (itemRowIndex == _thisLayer.HyGrid.RowsCount)
                               {
                                   Coordinate helperCoord = _thisLayer.GridCoordinates[(hygrid.ColsCount + 1) * (hygrid.RowsCount) + 1];
                                   colDistance = helperCoord.Distance(botChangedCoord);
                                   origonDis = helperCoord.Distance(hygrid.Origin);
                                   if (colDistance != helperCoord.Distance(hygrid.Origin))
                                   {
                                       colDistance = origonDis-colDistance;
                                   }

                                   helperCoord = _thisLayer.GridCoordinates[(hygrid.ColsCount + 1) * (hygrid.RowsCount - 1)];
                                   rowDistance = helperCoord.Distance(leftChangedCoord);
                                   origonDis = helperCoord.Distance(hygrid.Origin);
                                   if (rowDistance != helperCoord.Distance(hygrid.Origin))
                                   {
                                       rowDistance = origonDis-rowDistance;
                                   }
                                   origin = coordSecend;
                               }
                               else
                               {
                                   rowDistance = hygrid.Origin.Distance(leftChangedCoord);

                                   Coordinate helperCoord = _thisLayer.GridCoordinates[(hygrid.ColsCount + 1) * (hygrid.RowsCount) + 1];
                                   colDistance = helperCoord.Distance(botChangedCoord);
                                   origonDis = helperCoord.Distance(hygrid.Origin);
                                   if (colDistance != helperCoord.Distance(hygrid.Origin))
                                   {
                                       colDistance = origonDis-colDistance;
                                   }
                                   origin = botChangedCoord;
                               }
                           else if (itemRowIndex == _thisLayer.HyGrid.RowsCount)//移动hygrid定义点时操作
                           {
                               colDistance = hygrid.Origin.Distance(botChangedCoord);
                               
                               Coordinate helperCoord = _thisLayer.GridCoordinates[(hygrid.ColsCount + 1) * (hygrid.RowsCount - 1)];
                               rowDistance = helperCoord.Distance(leftChangedCoord);
                               origonDis = helperCoord.Distance(hygrid.Origin);
                               if (rowDistance != helperCoord.Distance(hygrid.Origin))
                               {
                                   rowDistance = origonDis-rowDistance;
                               }
                               origin = leftChangedCoord;
                           }
                           else//移动非Hygrid定义点时操作
                           {
                               colDistance = hygrid.Origin.Distance(botChangedCoord);
                               rowDistance = hygrid.Origin.Distance(leftChangedCoord);
                           }

                           this.InteractiveSystem.AskMoveCrossPoint(new MoveHGridCrossPointEventArgs(_thisLayer.HyGrid.RowsCount- itemRowIndex, itemColIndex, rowDistance,colDistance,origin.X,origin.Y));
                           _thisLayer.PtLayer.Select(itemIndex);
                       }
                       _isMoved = false;
                       movingNode = Coordinate.Empty;
                       
                       return;
                   }
               }

               if (_isDragging == false) return;
               _currentPoint = e.Location;
               _isDragging = false;

               //Application.DoEvents();
               IEnvelope env = new Envelope(coordFirst.X, e.GeographicLocation.X,
                   coordFirst.Y, e.GeographicLocation.Y);
               IEnvelope tolerant = env;



               if (Math.Abs(pointFirst.X - e.X) < 8 && Math.Abs(pointFirst.Y - e.Y) < 8)
               {
                   Coordinate c1 = e.Map.PixelToProj(new Point(e.X - 4, e.Y - 4));
                   Coordinate c2 = e.Map.PixelToProj(new Point(e.X + 4, e.Y + 4));
                   tolerant = new Envelope(c1, c2);
               }

               Map.MapFrame.SuspendEvents();
               HandleSelection(tolerant, env, e);
               Map.MapFrame.ResumeEvents();
               // Force an invalidate to clear the dotted lines, even if we haven't changed anything.
               e.Map.Invalidate();
               
               base.OnMouseUp(e);
           }
       }
       //void thisMouseUp(GeoMouseArgs e)
       //{
       //    if (Map == null) Map = e.Map;
       //    if (_isDragging == false) return;
       //    _currentPoint = e.Location;
       //    _isDragging = false;
           
       //    //Application.DoEvents();
       //    IEnvelope env = new Envelope(coordFirst.X, e.GeographicLocation.X,
       //        coordFirst.Y, e.GeographicLocation.Y);
       //    IEnvelope tolerant = env;



       //    if (Math.Abs(pointFirst.X - e.X) < 8 && Math.Abs(pointFirst.Y - e.Y) < 8)
       //    {
       //        Coordinate c1 = e.Map.PixelToProj(new Point(e.X - 4, e.Y - 4));
       //        Coordinate c2 = e.Map.PixelToProj(new Point(e.X + 4, e.Y + 4));
       //        tolerant = new Envelope(c1, c2);
       //    }

       //    Map.MapFrame.SuspendEvents();
       //    HandleSelection(tolerant, env,e);
       //    Map.MapFrame.ResumeEvents();
       //    // Force an invalidate to clear the dotted lines, even if we haven't changed anything.
       //    e.Map.Invalidate();

       //    Map.IsBusy = false;

       //}
       private void HandleSelection(IEnvelope tolerant, IEnvelope strict, GeoMouseArgs e)
       {
           Keys key = Control.ModifierKeys;
           if ((((key & Keys.Shift) == Keys.Shift) == false)
               && (((key & Keys.Control) == Keys.Control) == false))
           {
               // If they are not pressing shift, then first clear the selection before adding new members to it.
               //IEnvelope region;

               this.InteractiveSystem.GisManager.LayerSystem.ClearSelection();

           }

           if ((key & Keys.Shift) == Keys.Shift)
           {
               if (pointFirst.X == e.X && pointFirst.Y == e.Y)
               {
                   DotSpatial.Topology.Point clickPoint = new DotSpatial.Topology.Point(e.GeographicLocation);
                   List<IFeature> selectedF;
                   if ((selectedF = _thisLayer.PyLayer.Selection.ToFeatureList()) != null && selectedF.Count > 0)
                   {
                       for (int i = 0; i < selectedF.Count; i++)
                       {
                           if (selectedF[i].Contains(clickPoint))
                           {
                               _thisLayer.PyLayer.UnSelect(selectedF[i]);
                               _thisLayer.Select(tolerant, strict, this._editGridMode,true);
                               return;
                           }
                       }
                   }
               }
           }


           _thisLayer.Select(tolerant, strict, this._editGridMode,false);

       }

       protected override void OnUnload()
       {


           switch (_editGridMode)
           {
               case MFEDITGRIDMODE.None:
                   break;
               case MFEDITGRIDMODE.EditByNode:

                   

                   break;

               case MFEDITGRIDMODE.SelectByCell:


                   break;

               case MFEDITGRIDMODE.SelectByColCell:

                   break;

               case MFEDITGRIDMODE.SelectByRowCell:

                   break;

               case MFEDITGRIDMODE.SelectByLayer:


                   break;

               case MFEDITGRIDMODE.AddCol:

                   break;

               case MFEDITGRIDMODE.AddRow:

                   break;

               default: break;
           }
           
           base.OnUnload();
       }

        #endregion

      
    }
}
